#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time      :2021/7/1 15:48
# @Author    :cjw
import time
from typing import Optional

import allure
import pytest
from appium import webdriver
from appium.webdriver.webdriver import WebDriver
from app_wework.util.generate_data import GenerateData
from app_wework.util.file_operator import YmlOperator
from app_wework.setting import DES_CAPS, COMMAND_EXECUTOR
from app_wework.util.log import logger

driver: Optional[WebDriver] = None  # app驱动
gd: GenerateData = GenerateData()  # 数据生成器
des_caps = YmlOperator(DES_CAPS).data  # app启动参数


@pytest.fixture()
def app_driver():
	"""用例执行启动app"""
	global driver

	logger.info('启动app...')
	driver = webdriver.Remote(COMMAND_EXECUTOR, des_caps['simulator_android'])
	driver.implicitly_wait(5)
	yield driver, gd
	logger.info('关闭app...')
	driver.quit()


@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
	"""
	获取每个用例状态的钩子函数，进行失败用例截图

	具体执行过程如下：
	1、先执行when='setup'，返回setup 的执行结果
	2、然后执行when='call'，返回call 的执行结果
	3、最后执行when='teardown'，返回teardown 的执行结果

	运行用例的过程会经历三个阶段:setup-call-teardown,
	每个阶段都会返回的 Result 对象和 TestReport 对象，以及对象属性。
	:param item: 测试用例
	:param call: 用例步骤
	:return:
	"""
	outcome = yield  # 获取钩子方法的调用结果
	report = outcome.get_result()  # 从调用结果中获取测试报告

	# 只获取用例运行时失败的结果，即when='call'
	if report.when == 'call' and report.failed:
		now_time = time.strftime('%Y_%m_%d_%H_%M_%S')
		# 用例失败，添加allure报告截图
		if hasattr(driver, 'get_screenshot_as_png'):
			with allure.step('添加失败截图'):
				logger.info(f'添加失败截图')
				allure.attach(driver.get_screenshot_as_png(), f'失败截图_{now_time}',
				              allure.attachment_type.PNG)


def pytest_collection_modifyitems(items):
	"""
	测试用例收集完成时，将收集到的用例的name和nodeid的中文显示在控制台上
	name: 用例的名称
	nodeid：用例的路径
	:param items: 收集到的所有用例
	:return:
	"""
	for item in items:
		item.name = item.name.encode('utf-8').decode('unicode_escape')
		item._nodeid = item.nodeid.encode('utf-8').decode('unicode_escape')
